package jbrowser.gui;

import java.net.URI;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.SwingWorker;
import jbrowser.services.ClassService;
import jbrowser.services.ServiceRegistry;

public class ProxyPage implements Page {

    //private Tab tab;
    private static final Logger logger = Logger.getLogger(ProxyPage.class.getName());
    private Page page;
    private JLabel proxyComponent = null;
    private boolean loaded = false;
    private long startTime;
    private static ImageIcon proxyIcon16;
    private static ImageIcon proxyIcon128;
    private static String proxyTitle = "Loading...";
    private static Page.CacheMode proxyCacheMode = Page.CacheMode.NEVER;

    ProxyPage(final Tab tab, final URI uri) {
        //this.tab = tab;
        startTime = new Date().getTime();
        SwingWorker<Page, Object> worker = new SwingWorker<Page, Object>() {
            @Override
            public Page doInBackground() {
                try {
                    Iterator<ServiceRegistry> registries = ServiceLoader.load(ServiceRegistry.class).iterator();
                    if (registries.hasNext()) {
                        ServiceRegistry serviceRegistry = registries.next();
                        List<ClassService> classServices = serviceRegistry.get(ClassService.class);
                        for (ClassService classService : classServices) {
                            Class clazz = classService.get(uri);
                            if (clazz != null) {
                                return (Page) clazz.newInstance();
                            }
                        }
                        logger.log(Level.WARNING, "Appropriate ClassService not found! Can't load uri: {0}", uri);
                        return new ErrorPage("Appropriate ClassService not found!", "Can't load uri: " + uri);
                    } else {
                        logger.log(Level.WARNING, "ServiceRegistry not found!", "Can't load any page.");
                        return new ErrorPage("ServiceRegistry not found!", "Can't load any page.");
                    }
                } catch (Exception ex) {
                    logger.log(Level.SEVERE, null, ex);
                    return new ErrorPage(ex);
                }
            }

            @Override
            protected void done() {
                try {
                    loaded = true;
                    page = get();
                    long totalTime = new Date().getTime() - startTime;
                    tab.setStatus("Load time: " + Long.toString(totalTime).concat(" ms"));
                    tab.setIcon(page.getIcon());
                    tab.setTitle(page.getTitle());
                    tab.remove(proxyComponent);
                    tab.add(page.getComponent(), java.awt.BorderLayout.CENTER);
                } catch (Exception ex) {
                    logger.log(Level.SEVERE, null, ex);
                    tab.setPage(new ErrorPage(ex));
                }
            }
        };
        worker.execute();
    }

    @Override
    public JComponent getComponent() {
        if (loaded) {
            return page.getComponent();
        } else {
            if (proxyIcon128 == null) {
                proxyIcon128 = new ImageIcon(getClass().getResource("/images/loading80.gif"));
            }
            if (proxyComponent == null) {
                proxyComponent = new JLabel();
                proxyComponent.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
                proxyComponent.setIcon(proxyIcon128);
            }
            return proxyComponent;
        }
    }

    @Override
    public String getTitle() {
        if (loaded) {
            return page.getTitle();
        } else {
            return proxyTitle;
        }
    }

    @Override
    public Page.CacheMode getCacheMode() {
        if (loaded) {
            return page.getCacheMode();
        } else {
            return proxyCacheMode;
        }
    }

    @Override
    public Icon getIcon() {
        if (loaded) {
            return page.getIcon();
        } else {
            if (proxyIcon16 == null) {
                proxyIcon16 = new ImageIcon(getClass().getResource("/images/loading16.gif"));
            }
            return proxyIcon16;
        }

    }
}
